{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "c:\\Users\\12743\\ai_exercise_lab3\\part2_sklearn\n"
     ]
    }
   ],
   "source": [
    "import pandas as pd\n",
    "import numpy as np\n",
    "import matplotlib.pyplot as plt\n",
    "\n",
    "from sklearn.linear_model import LinearRegression, Ridge, Lasso\n",
    "\n",
    "from sklearn import datasets\n",
    "from sklearn.model_selection import train_test_split\n",
    "import os\n",
    "print(os.getcwd())\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Linear Regression with Polynomial Curve Fitting\t\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [],
   "source": [
    "#data loading\n",
    "df = pd.read_csv('globalTemp.csv')\n",
    "df = df.dropna()\n",
    "x = df['Year'].to_numpy()\n",
    "y = df['Actual Temp'].to_numpy()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "<matplotlib.collections.PathCollection at 0x26baa9caa50>"
      ]
     },
     "execution_count": 6,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "image/png": "iVBORw0KGgoAAAANSUhEUgAAAjQAAAGdCAYAAAAFcOm4AAAAOnRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjEwLjYsIGh0dHBzOi8vbWF0cGxvdGxpYi5vcmcvq6yFwwAAAAlwSFlzAAAPYQAAD2EBqD+naQAANshJREFUeJzt3Q9wVFWW+PET/iNClj8iZCGAi4JGjEEYR/zNCBsWpBgcwxSMI7IRdx0RATEUKzj+HxGpVYRVhJFyhK3RdbAkjOuuUuqohEWEEEAdFQxGRJSJuA6R4IaR9K/OdbqnE7o73Z3X/d597/up6grdef14fbvz3ulzz703JxQKhQQAAMBibdw+AAAAgNYioAEAANYjoAEAANYjoAEAANYjoAEAANYjoAEAANYjoAEAANYjoAEAANZrJz7R2Ngon332mXTt2lVycnLcPhwAAJAEnd/366+/lry8PGnTJv08i28CGg1m+vfv7/ZhAACANBw8eFD69esnEvSARjMz4Qbp1q2b24cDAACSUFdXZxIS4eu4BD2gCXczaTBDQAMAgF1aWy5CUTAAALAeAQ0AALAeAQ0AALAeAQ0AALAeAQ0AALAeAQ0AALAeAQ0AALAeAQ0AALAeAQ0AALAeAQ0AALCeb5Y+AAAAmbHrk6+k5ki9DOrVRYryu4sXEdAAAIC4HnjxfVn9xkeR+zMvO0sWTjhXvIYuJwAAEDczEx3MKL2vj3sNAQ0AAIhJu5lSedxNBDQAACAmrZlJ5XE3EdAAAICYtABYa2ai3XjZWZ4sDKYoGAAAxKUFwOML+jDKCQAA2K0ov7tnA5m0u5w2b94skyZNkry8PMnJyZGNGzfG3XbmzJlmm+XLlyfc58mTJ+WOO+6QQYMGSefOneXv/u7v5Je//KWEQqFUDw8AAARQyhma+vp6KSwslOuuu04mT54cd7vy8nLZtm2bCXxasnTpUlm1apWsW7dOCgoKpLKyUmbMmCG5ubkyd+7cVA8RAAAEYDK9VgU0EyZMMLdEDh06JHPmzJFNmzbJxIkTW9zn1q1b5cc//nFk24EDB8p//Md/yPbt21M9PAAAEJDJ9DI6yqmxsVGmT58uCxYsMNmWZIwaNUpeffVV2bdvn7m/Z88e2bJlS8LAqaGhQerq6prcAABAcCbTy2hRsHYftWvXLqWuooULF5qAZOjQodK2bVtTU7N48WKZNm1a3OcsWbJE7rnnHoeOGgAAtDSZnpe7nhzN0OzcuVNWrFgha9euNcXAyVq/fr089dRT8vTTT0tVVZWppXnwwQfNz3gWLVokR48ejdwOHjzo0KsAACC4Blk0mV7GApqKigqpra2V/Px8k6XR24EDB2T+/PmmLiYe7Z7SLM1VV10lw4YNM11Wt9xyi8nCxNOxY0fp1q1bkxsAAAjOZHoZ63LSQGTs2LFNHhs/frx5XEctxXP8+HFp06ZpbKVdT1qPAwAAsmuhJZPptSqgOXbsmFRXV0fu19TUyO7du6VHjx4mM9OzZ88m27dv31769OkjQ4YMiTxWXFwsJSUlMnv2bHNf57XRmhl9vhYS79q1S5YtW2aGhgMAgOwrsmAyvVYFNDpHzJgxYyL3y8rKzM/S0lJTO5OM/fv3y5EjRyL3H3nkETOx3qxZs0yXlc5dc8MNN8idd96Z6uEBAIAAygn5ZDpeHSWlE/FpgTD1NAAABOv6zWrbAADAegQ0AADAegQ0AADAegQ0AADAegQ0AADAegQ0AADAegQ0AADAegQ0AADAegQ0AADAegQ0AADAegQ0AADAegQ0AADAegQ0AADAegQ0AADAegQ0AADAegQ0AADAegQ0AADAegQ0AADAegQ0AADAegQ0AADAegQ0AADAegQ0AADAegQ0AADAegQ0AADAegQ0AADAegQ0AADAegQ0AADAegQ0AADAegQ0AADAeu3cPgAAAOC+XZ98JTVH6mVQry5SlN9dbENAAwBAwD3w4vuy+o2PIvdnXnaWLJxwrtiELicAAAKemVkdFcwova+P24SABgCAAKs5Up/S415FQAMAQIAN6tUlpce9ioAGAIAAK8rvbmpmot142VnWFQZTFAwAQMAtnHCujC/owygnAABgt6L87lYGMmF0OQEAAOulHNBs3rxZJk2aJHl5eZKTkyMbN26Mu+3MmTPNNsuXL29xv4cOHZJrrrlGevbsKZ07d5Zhw4ZJZWVlqocHAAACKOWApr6+XgoLC2XlypUJtysvL5dt27aZwKclX331lVx66aXSvn17efHFF+W9996Thx56SLp3tzf1BQCAW3Z98pVsqPrUurlkslpDM2HCBHNrKdsyZ84c2bRpk0ycOLHFfS5dulT69+8vTz75ZOSxQYMGpXpoAAAE3gM+mPXXEzU0jY2NMn36dFmwYIEUFBQk9Zznn39eRowYIVOmTJHevXtLUVGRrFmzJuFzGhoapK6urskNAIAg2+WTWX89EdBotqVdu3Yyd+7cpJ/z0UcfyapVq+Tss882WZ0bb7zRPH/dunVxn7NkyRLJzc2N3DTDAwBAkNX4ZNZf14dt79y5U1asWCFVVVWmGDiVrI5maO6//35zXzM07777rqxevVpKS0tjPmfRokVSVlYWua8ZGoIaAECQDfLJrL+uZ2gqKiqktrZW8vPzTZZGbwcOHJD58+fLwIED4z6vb9++ct555zV57Nxzz5VPPvkk7nM6duwo3bp1a3IDACDIinwy6286HM3QaO3M2LFjmzw2fvx48/iMGTPiPk9HOO3du7fJY/v27ZMBAwY4eXgAAPjeQh/M+puVgObYsWNSXV0duV9TUyO7d++WHj16mMyMziMTTYdi9+nTR4YMGRJ5rLi4WEpKSmT27Nnm/i233CKjRo0yXU5Tp06V7du3y+OPP25uAAAgWLP+ZiWg0cnuxowZE7kfrmPRWpe1a9cmtY/9+/fLkSNHIvdHjhxp5q3Ruph7773XDNnWyfimTZuW6uEBAIAk6egnv2RyckKhUEh8QIuCdbTT0aNHqacBAMCS+Wqcun6zlhMAAAGb6XeXD+erYbVtAAACljmpSTBfja1dT2RoAADwiGxlTgb5cL4aAhoAAAI202+RD+erocsJAACPyGbmZKHP5qshQwMAgEdkO3NSlN9dJg/vZ30wo8jQAADgoflb0s2c7PLRnDLpIKABAMBjo5BSnen3AY/MKeMmupwAALB4/hYvHpMbCGgAAPDYKKRMHtOuDE/a5xa6nAAAsHj+llSO6QEfd02RoQEAwIVRSE5lSpI9pl0+75oiQwMAQJbnb0klUxI9eknF+n8XJnFMflzuIBoBDQAAGR6FlEymRAOS5vtsHvhEax4EFbVwTF7sLnMSXU4AAGSJBjPPVh6M+bvmGZRYgU9ruouKfLjcQTQyNAAAZEGibEusTEkyI6dS7S5a6LPlDqIR0AAAkGEtZVtiZUqS6QpKp7uoqBXdZV5GQAMAQIbFy7Zc/b3+MmVE/5gBRriLKF4g5KfuIicQ0AAAkGHxMinxgpl4XUTKj91FTiCgAQAgw2JlW5LNsDTvIiKQiY2ABgCALEhUkJvJlbJ3BWQVbgIaAACyJFZBbiaXI3jAx0sdNMc8NAAAuCSTyxHs8vlSB80R0AAA4MPVu2s8uDJ4JhHQAADgkkwuRzDI50sdNEdAAwCASzK5HEGRz5c6aC4nFAqFxAfq6uokNzdXjh49Kt26dXP7cAAASFqQRznVOXT9JqABACBDvB5M+On6zbBtAAAyIEhDpr2AGhoAAByWrSHTur8NVZ/6dih2KsjQAADgsERDpp3qeiID1BQZGgAAHJbpIdNBmzQvGQQ0AAA4LNNDpoM2aV4y6HICACDLi1G2VtAmzUsGGRoAADJUgKtBzOTh/Rwfsh20SfOSQYYGAAALC3AzmQGyEQENAABpFOBqMOF2EKH/v9vH4BV0OQEAkAAFuD4NaDZv3iyTJk2SvLw8ycnJkY0bN8bddubMmWab5cuXJ73/Bx54wDxn3rx5qR4aAACOowDXpwFNfX29FBYWysqVKxNuV15eLtu2bTOBT7J27Nghv/rVr+SCCy5I9bAAAMgICnB9WkMzYcIEc0vk0KFDMmfOHNm0aZNMnDgxqf0eO3ZMpk2bJmvWrJH77rsv1cMCACBjKMANYA1NY2OjTJ8+XRYsWCAFBQVJP++mm24ywc/YsWOT2r6hocGs0Bl9AwAgUzI1BBseHeW0dOlSadeuncydOzfp5zzzzDNSVVVlupyStWTJErnnnnvSPEoAAOAnjmZodu7cKStWrJC1a9eawt5kHDx4UG6++WZ56qmnpFOnTkn/X4sWLZKjR49GbrofAAAQTI4GNBUVFVJbWyv5+fkmS6O3AwcOyPz582XgwIFxgyB9zvDhwyPPeeONN+Tf/u3fzL9PnjwZ83kdO3aUbt26NbkBAIBgcrTLSWtnmtfAjB8/3jw+Y8aMmM8pLi6Wd955p8ljuu3QoUPl1ltvlbZt2zp5iAAAwIdSDmh0NFJ1dXXkfk1NjezevVt69OhhMjM9e/Zssn379u2lT58+MmTIkCZBTElJicyePVu6du0q559/fpPndOnSxeyn+eMAAACOBDSVlZUyZsyYyP2ysjLzs7S01NTOJGP//v1y5MiRVP9rAACAmHJCoVBIfECHbefm5poCYeppAAAI1vWbxSkBAIhaiJLJ8+xEQAMAgK4l+OL7TVbV1uUOdIZg2IHVtgEAgaeZmehgRul9fRx2IKABAASedjOl8ji8hy4nAEDgac1MKo83R+2N+whoAACBp0GI1sxEdzvdeNlZSQUn1N54AwENAMA3WpMp0SBkfEGflJ4fr/ZG90OmJrsIaAAAvuBEpkSDkFQCkUS1NwQ02UVRMADAem6NUopXY3Pgy3pGSGUZAQ0AwHpujVIK1940t+LVail5bKvJGiE7CGgAABL0UUqtod1a5bNGyc3Fg0/5HXPZZA8BDQDAerEyJcmOUnLq/x/QM3bwxFw22UFRMADAF9IZpeSXLBHI0AAAfESDmMnD+5mf2tWzoerTrHX5uJ0lCjoyNAAA33Frsju3s0RBRkADAPAVtye7S3UuGziDLicAgK+w0GQwEdAAAHyF4txgIqABAPgKxbnBRA0NAMB3KM4NHgIaAIAvV9SmODdYCGgAANZwazg2vI8aGgCAFVmZh1/e68qK2rADGRoAgFVZmea0+4muJZChAQBYNUlecwzHhiKgAQB4VkuT4TEcG2F0OQEAPCte9uXm4sEyekhvghlEkKEBAFg3Sd4t/zCEYAZNkKEBAHgak+QhGQQ0AABPToyXrUny0jkeeA8BDQAgsBPjee14kD5qaAAArg3BdnNiPK8dD1qHgAYA4OoQ7JaGZgfleNA6dDkBAFwdgu3WxHjJHA/1NfYgQwMAcHUItluBQkvHo/U1JY9tlbL1e8xPvQ/vygmFQiHxgbq6OsnNzZWjR49Kt27d3D4cAEAcXst6xDoefUyDmObKZ43yxDH7SZ1D12+6nAAAWZXJIdhOHU+i+hovHTv+ii4nAAA8Xu+DDAQ0mzdvlkmTJkleXp7k5OTIxo0b4247c+ZMs83y5csT7nPJkiUycuRI6dq1q/Tu3VuuvPJK2bt3b6qHBgCAL+t9kIEup/r6eiksLJTrrrtOJk+eHHe78vJy2bZtmwl8WvLGG2/ITTfdZIKab7/9Vm677TYZN26cvPfee9KlC9EwANjGa3Uy6WDJBZ8HNBMmTDC3RA4dOiRz5syRTZs2ycSJE1vc50svvdTk/tq1a02mZufOnfLDH/4w1UMEALgo27PvZjJ48lq9D7JYFNzY2CjTp0+XBQsWSEFBQVr70Epn1aNHj7jbNDQ0mFt0lTQAb/PDt3akN/uuZjoy8Z6zdAEyVhS8dOlSadeuncydOzftgGjevHly6aWXyvnnn5+w7kaHeYVv/fv3b8VRA8g05vQIhmzOvtuapQt0mw1Vn7LMgY84mqHRLqIVK1ZIVVWVKQZOh9bSvPvuu7Jly5aE2y1atEjKysqaZGgIagBvyva3dgRjdFC6Q6vJ6viToxmaiooKqa2tlfz8fJOl0duBAwdk/vz5MnDgwBafP3v2bHnhhRfktddek379+iXctmPHjmYCnugbAG9izZzgyObooHSCJxak9C9HMzRaOzN27Ngmj40fP948PmPGjLjP08mKtYhYR0a9/vrrMmjQICcPC4DLmNMjWLI1OigcPEUHKC0FT0yY518pBzTHjh2T6urqyP2amhrZvXu3KeDVzEzPnj2bbN++fXvp06ePDBkyJPJYcXGxlJSUmIxMuJvp6aeflt/97ndmLprDhw+bx7U2pnPnzq15fQA8IJ0LD+yWrdFBqQZPBNf+lXJAU1lZKWPGjIncD9exlJaWmuHWydi/f78cOXIkcn/VqlXm5+jRo5ts9+STT8q1116b6iEC8CDm9IAXgieCa/9icUoAQOCG5dt0rH5Xx+KUAACv8PrIoeYBDBPm+Q8BDQDA18PyvR5swRmstg0A8O2wfIZpBwcBDQCgVbw8csjLwRacRUADALBmMj0/BVtwFjU0AADfDstnmHZwMGwbAOB7DNP2LoZtAwB8zckghGHa/kdAAwDwXNaDodZIFQENAMBTAYfX57WBNzHKCQDgqbldGGqNdBDQAAA8FXAw1BrpIKABAHgq4PDyvDbwLmpoAACem9vFq/PawLuYhwYAkBbmdoETmIcGgGdwYQvm+8vcLvASAhoArcJ8If7G+wtbUBQMwLPDd+Eu3l/YhIAGQNqYL8TfeH9hE7qcAKSN+UL8zan3lxorZAMZGgBpY74Qf3Pi/dUanJLHtkrZ+j3mp94HMoFh2wBaLd1v4Hxz9//7q0FMc+WzRvF+I4Jh2wA8I53hu4yesUe6w7MT1eAQ0MBpdDkByDpGz7hD23dD1adZa2dqrJBNZGgAZB3f3LPPjYxYNpZIAMIIaABkvf6Cb+7eyIjpWkmZDi5YkwnZQkADIGNBTMWHX0j5rs9OyQrwzT1YGTGWSEA2ENAAyGjXRrysAN/cs8fLGTFGusEpBDQAMtq1kSgrwDf37PBqRoyRbnASAQ0AxyQzJb4XsgJB5LWMmJt1PfAnAhoAjmkpWPFCViDIvJQRixf8Plt50Pz0ynHCHgQ0ADLatTG5KE/+39lneCIrAO8Hv09vP2hudD8hVSx9AMBxFHqitQXkiiUSgqGOpQ8AeJWXujbg/boe7WbSrExzTLSIVLD0AQDANRqwTBnRP+bvKCBHKghoAACeqL2KRgE5UkWXEwAkgbqgzLaD14aVwz4ENACQhQng/BAQZXoiPGqvkNUup82bN8ukSZMkLy9PcnJyZOPGjXG3nTlzptlm+fLlLe535cqVMnDgQOnUqZNcfPHFsn379lQPDQCyNgGcPp5KIFDy2FYpW7/H/NT7QWwHwFMBTX19vRQWFpoAJJHy8nLZtm2bCXxa8tvf/lbKysrkrrvukqqqKrP/8ePHS21tbaqHBwBZW9gxSIFAa9sB8FxAM2HCBLnvvvukpKQk7jaHDh2SOXPmyFNPPSXt27dvcZ/Lli2T66+/XmbMmCHnnXeerF69Wk477TT59a9/nerhAcgSvSBvqPrUigtza461tQs7ZioQyHb7e3mBSyAjNTSNjY0yffp0WbBggRQUFLS4/YkTJ2Tnzp2yaNGiyGNt2rSRsWPHyptvvhn3eQ0NDeYWPTEPgOywaVHB1h5raxZ21GDjwJf1jgcCbrS/Vxe4BDIW0CxdulTatWsnc+fOTWr7I0eOyMmTJ+XMM89s8rje/+CDD+I+b8mSJXLPPfe0+ngB+HdRQaeONZ0ROIlmwW1NIOBm+zMSCYEJaDTTsmLFClMHo8XAmaQZHa27ic7Q9O8fe3ImAM5J1IXitQuck8eaygicWEGHurl4sIwe0rtV7eR2+zMSCYGYWK+iosIU8ubn55ssjd4OHDgg8+fPNyOYYunVq5e0bdtW/vjHPzZ5XO/36dMn7v/VsWNHs+ZD9A1A5tlUS+HGsWowE14xurkBPVuf1bCp/QFrAxqtnXn77bdl9+7dkZuOctJ6mk2bNsV8TocOHeSiiy6SV199tUkdjt6/5JJLnDw8AAGb1TXbxxoenh1rXSKngg6b2h/wdJfTsWPHpLq6OnK/pqbGBC49evQwmZmePXs22V5HOWmmZciQIZHHiouLzSip2bNnm/vadVRaWiojRoyQ733ve2beGh0erqOeAHiPTbUU2TrWeN1MmQg6bGp/wLMBTWVlpYwZMyZyP1zHogHJ2rVrk9rH/v37TTFw2E9/+lP54osv5M4775TDhw/LhRdeKC+99NIphcIAvMOmWopsHGu82parv9ffLL7o9P9vU/sD2ZATCoVC4gNaFJybmytHjx6lngZA1mmGRrubmiufNYrAA8jC9ZvVtgHAgUntqG0B3MXilADg0KR21LYA7iGgAYAkV8dOZlI7alsAdxDQAECSWRi3J7UDEB81NACQ5OrYTGoHeBcBDQBEaSkL49XCX5tWPwcygS4nAIjSUhbGi4W/Nq1+DmQKGRoAiJJMFkb/PXl4P08EM4m6yIAgIUMDIDCjlJLlxSxMul1krWkHwCYENAB8x4kumGSHX7sdMCTqIqMrCkFClxMAX8lmF0x4de2y9XvMT73vlS4yRVcUgoQMDQBfydZcMclMspctsbrIdMRTLMyZA78ioAHgK9maK8Zrk+w17yJjzhwEDV1OAHwlW3PFeD1gSLUdmMcGtssJhUIh8QGnlh8H4A/ZKNZtXnSrAcOtHiu6TaYdKB6GH67fBDQAPMHt0UJBO+7o49eC5ubKZ42y8vUguNdvamgAuM7mDIHtq2t7rRYISBc1NAB8M8zaj3UgmX5NXq8FApJFhgZA0l0omehecSpDYHOWx83XFC4ebl4LRHYGtiGgAZDUBTRTF1cnMgRemhPGKdl8TTYt9QDEQ5cTgBa7fjI5+64Tw6wTZXls7WJ6fW9tVl+TlxbcBNJBhgZAwgvls5UH5YyuHeM+x4kLYGszBH6pA2meBYvlwJf1Jugh8ACaIqABkPDi//T2gyk/J9ujhfxQBxIrCxbLilerzc0PNUKAkwhoAMQNChLxWsBgex1IvAzZzcWDzU8NYvxUIwQ4jYAGwClBgXYzxcrM6MV1QM8ung0YbJ4TJl62a/SQ3swVAySBgAZAE+ELZKyARi+uXEAzI51uM9tqhIBMIqAB4LmalObz3di+vEBru83cfj8AG7CWE4C43Agkmo/0ubB/ruw+eDRyP8jFsEEJ7BAsdSxO2RQBDWC/eAslxqrlofsL8Ic6h67fTKwX8HViAC9JdtI4HfGjgY9mcwBAUUOTpFjTvts8RBTeQTdC+kWuDF0GEEZAk4R40777bSG8IFx0vfY6nFgfyWuvqTViFb82r6FpjqHLABQBjUNpcD9/U/TLKsZeex1OLD7otdeUqZE+2la6tlHzyeUUQ5fT56dgGCCgSUKyJ0w/flP0yyrGXnwdrZ0szYuvKVMT5IXvN3zb6Muhy04HFsnsL1EwTKADGxHQODglvB+/KfplhlIvvo7WLqjoxdeUabYvb5CNLFsy+0sUDG/6w2HfZf0QDIxySpL+QZfPGiXLphaan/pHHs0v3xT9uoqxF19HOFBO93PkxdeUDdo+k4f388XfW7zAIt2RlMnuL14wrN16Th4PkE1kaNJMg+tPv31TjMUvM5R69XW0JuPg1deE5DmdZUt2f6kGvX7O+iHAAc3mzZvlX//1X2Xnzp3y+eefS3l5uVx55ZWR3999993yzDPPyMGDB6VDhw5y0UUXyeLFi+Xiiy+Ou8+TJ0+a5/3mN7+Rw4cPS15enlx77bVy++23S05OjniVzQvhBTHN79XX0ZrPkVdfE8SVLFuy+4sXDOtkhRReIzABTX19vRQWFsp1110nkydPPuX355xzjjz66KNy1llnyTfffCMPP/ywjBs3Tqqrq+WMM86Iuc+lS5fKqlWrZN26dVJQUCCVlZUyY8YMM3Pg3LlzJYgyWZSXzr79Erz55XX4/TUFhdNZtlT2Fy8YJusHW7Vq6QPNnjTP0MSb0viVV16R4uLimNv86Ec/kjPPPFOeeOKJyGM/+clPpHPnziZrE7SlDzI5FNePw3yDKJ2glJEr3uXGKKdsHg+Qjet3RmtoTpw4IY8//rg5UM3qxDNq1Ciz3b59+0yGZ8+ePbJlyxZZtmyZBE0mh+L6eZhvkKQTlBLIBivL1tr9kfWDjTIyyumFF16Q008/XTp16mS6nF5++WXp1atX3O0XLlwoV111lQwdOlTat28vRUVFMm/ePJk2bVrc5zQ0NJioLvrmB4mK+ry8b3h3VIzTI2kAIDABzZgxY2T37t2ydetWufzyy2Xq1KlSW1sbd/v169fLU089JU8//bRUVVWZWpoHH3zQ/IxnyZIlJvMTvvXv398XC1JmcihuUIf5+kk6QWkyz2HhVQC2y0iXU5cuXWTw4MHm9v3vf1/OPvtsUx+zaNGimNsvWLAgkqVRw4YNkwMHDpigpbS0NOZzdF9lZWWR+5qhcTqocSNNn8mhuKnum35070kmKG3+vrX0nKB1R/G5BvwpK/PQNDY2mi6ieI4fPy5t2jRNFrVt29Y8L56OHTuaW6a4WW+SyaG48dbJaf5/Be0iZ4uWgtJ471u85wStrorPNeBfKQc0x44dM0Oww2pqakz3Uo8ePaRnz55mzpkrrrhC+vbtK0eOHJGVK1fKoUOHZMqUKZHn6GinkpISmT17trk/adIk87z8/HwzbHvXrl2mIFiHhrvF7WnlM1mUF73vWCd4vZgF6SJnm3gBb6LgJN5z3P6cZ1PQgjcgaFIOaHSOGK2RCQt3+2jX0OrVq+WDDz4wtS8azGiAM3LkSKmoqDCBStj+/fvN78MeeeQRueOOO2TWrFmm1kYn1rvhhhvkzjvvFLcEod4k3gm+Y7s2gbnI2SpWwNtScBLrOUH4nIcFKXgDgijlgGb06NGSaOqaDRs2tLiPjz/+uMn9rl27yvLly83NK4IwrXyqo5v8eJHzk3SCkyB8zltqhz+fbDQF0dTUAHZjLacATysf7wSv0583fNvom4tcUIpAUwlOotvE75/zRO1zYf9cufW5dyL3qakBAjpTsJe4PVOwrRfN5jU0egG89S8n9ESvyZbXG8Qi0JbemyC2Saz20cxMdDATVj5rlKc/04Df1Dl0/SagcYBTFwi3goRU/19bLoj6ukoe25rRC5ZtSxBko01sod1MZev3nPL4sqmFMnl4P1eOCQiiOhuWPggCp0ZOuBkkpDKiyqaRIpkuArVxCQIKY71TEG1LlhMI9EzBQeLEcgI2TU1v0/IJmbxgZWoJgkzP2Ov2RdyLNTXRslUrpoGtZso0Q6Q/9T6A1iFD44ELhE3fmm26IGZyBE8671lLz8lG9iZIo5qS4UZBtE1ZTsAmBDQeuEAQJNh3wUrnPUv0nGxe5Pw0qsmJbptsryxt0xcYwCYENB64QBAkZFYmLljpvGeJnqPdTNm8yGX7Ip4JbtcjpcumLzCATRjl5CEUCdrHqVFOjD5Kje3tlWi6BCBo6hjl5D9++NYcNOm8Z7GeEyt7M7koL9I9wefCX902tmU5ARsQ0AAevMhVfPiFbNj1mbnZ1J2SLX7otuELDOAshm0DHqIXOL0ol/8lkPH6MP4gDrkG4E1kaACPsb07JVvotgEQjYAG8Bg/dKdkC902AMLocgI8hu4UAEgdGZoM8MMq1XAX3Snu4O8TsBcBTRYn+7J1IrCgc+siR3dKdvH3CdiNgMZBiaavD/871u+4aHk3iNHh09EjjrjI+RPrKwH2I6DJwuiU1/fWyhdfN8R9DidMb39Tj6aPa6amfds2dEv4CCPLAPsR0Dgo3iiUFa9Wp/wcv/NqrUKsb+rN3frcO0llbLz6GnEqRpYB9iOgcVCs6esTCerIFS/XKsT7ph5PvG4JL79G2L9ALIBTEdBkcHTKgS/rY2Znrv5ef5kyon8gT5Zer1VI5xt5824Jr79GxMbIMsBuzEOTAXoinDy8n4we0jvm790IZvQiu6HqU9enz09Uq+DVOWB0kchlUwtl6U+GJQyCwm2sNVNefo1o+W+XYAawDxmaAKSxvdT9YUOtQqJv6vpYrPczUSGxF18jAPhNTigUCokP1NXVSW5urhw9elS6desmXuJmcaj+3yWPbT3l8fJZo1z7Ftr84q9Bwa0W1Zc0fz/jtXE0214jANh2/SZD4/MJ0rw4HNX2WoXm72e8Nr65eLAM6NnFytcIALYhoPG5bHTxpJOB8tMsuPHaUmuo3H6NDB0HEBQEND6/2GS6jsdL9TluSaaN3QgseG8ABAk1NC5pzcUmnYtjss9JZd9erM9xU7y2cyOw4L0BYAtqaCzWmnlK0r04JtPFk+q+vVif46ZYbezWnDS8NwCChnloLJqLJd7F0Ym5ZdLZtw1DsN3m1rw7vDcAgoaAxgXpXmwyeXFMZ9+xJqFjunhvBBa8NwCChi4nF6RbqJvJi2O6+7Z9CLafJ1fkvQEQJBQFuyid4t5MTkpn+4R3XsbwaQDI7PWbgMZCmbw4cuEFAGQTAU2AA5pkEZwAALyOYdtIiEnVAABBwignH8rk8G4AAHwR0GzevFkmTZokeXl5kpOTIxs3bmzy+7vvvluGDh0qXbp0ke7du8vYsWPlrbfeanG/hw4dkmuuuUZ69uwpnTt3lmHDhkllZWWqhwcX5z5piQZUG6o+9VRg5cVjAgBkocupvr5eCgsL5brrrpPJkyef8vtzzjlHHn30UTnrrLPkm2++kYcffljGjRsn1dXVcsYZZ8Tc51dffSWXXnqpjBkzRl588UWz3YcffmgCIvhjUjUvdoF58ZgSoSYKADJUFKwZmvLycrnyyitbLPZ55ZVXpLi4OOY2CxculP/5n/+RioqKdA+FomAPD8H24rpCXjwmPwVfAJDt63dGa2hOnDghjz/+uDlQzerE8/zzz8uIESNkypQp0rt3bykqKpI1a9Yk3HdDQ4NphOhbEMXrMtGLnV6cl00tND/dnE/Gi11gXjymeKiJAgCXRjm98MILctVVV8nx48elb9++8vLLL0uvXr3ibv/RRx/JqlWrpKysTG677TbZsWOHzJ07Vzp06CClpaUxn7NkyRK55557JMha+taezIKUQe0C8+IxxcNCkwDgUoZGa2F2794tW7dulcsvv1ymTp0qtbW1cbdvbGyU4cOHy/3332+yMz//+c/l+uuvl9WrV8d9zqJFi0x6Knw7ePCgBIlN39rdWFeopWLfWMc0uSjPBAlea0Obgi8A8FWGRkc4DR482Ny+//3vy9lnny1PPPGECUJi0SzOeeed1+Sxc889V5577rm4/0fHjh3NLahs+9aezXWFkq03iT6mig+/kA27PjO3RM8J2npQAGCLrEyspxkYrXmJR0c47d27t8lj+/btkwEDBmTh6Lwv1uiWeN/OD3z5XYbBixe7bHSBxctcaeAS6/8OP1a2fk/Sz3EDC00CgMMBzbFjx8wQ7LCamhrTvdSjRw8zh8zixYvliiuuMFmXI0eOyMqVK80cM1rwG6ajnUpKSmT27Nnm/i233CKjRo0yXU7aPbV9+3ZTTKy3oIuXbYj1rV2teLXa3LyUYchm0KcBXaqZK1uyXV6piQIAXwQ0Otmd1siEaSGv0uJdrXn54IMPZN26dSaY0QBn5MiRZjh2QUFB5Dn79+83vw/TbXT4t3ZJ3XvvvTJo0CBZvny5TJs2TYKspWxD+Fv763trTRATb7ugBX2p1ptQowIAAQxoRo8eLYmmrtmwYUOL+/j4449PeexHP/qRuSG1zIH+9FKGIduTv8UK+pprqd6EGhUAsB+LU3pYspkDr2QY3Jj8LV4wd3PxYBnQs0vSgRU1KgBgNxan9LBkhzu7MSzaK8PI4wVto4f0lsnD+6XUBrptqs8BAHgDGRqPSzZz4HaGwa1uL7qLAACKgMYCyY5ucXMUjJvdXm4HcwAA99HlBEe43e1FdxEABBsZGjiGTAkAwC0ENHAUk78BANxAlxMAALAeGRp4QrYn5AMA+AsBDVznxoR8AAB/ocsJrkp1Qj59fEPVpxmfsA8AYBcyNHBVKhPykckBAMRDhgauSnZCPreWVgAA2IGABlZMyJcokwMAAF1OsGJCPq+sKA4A8CYyNPCElpYucHtpBQCAt5GhgTVYWgEAEA8BDazC0goAgFjocgIAANYjoAEAANajywkZxRpNAIBsIKBBxjgxsy8BEQAgGQQ0yIh4M/vqKKVkAxOWOgAAJIsaGmREa2f2TWapAxaqBACEkaFBRrRmZl8NUJ6tPJhw0UqyNwCAaGRokBHpzuyrgUrJY1vl6e0H4wZELFQJAGiODA08M7NvrEAlVkCk3UyJsjcAgOAhoIFnZvaNV19z9ff6y5QR/SP7YaFKAEBzdDnBM+IFJNHBjGKhSgBAc2Ro4BnhQCW62yleoMJClQCAaDmhUCgkPlBXVye5ubly9OhR6datm9uHg1ZgMj0ACI46h67fZGjgOayoDQBIFTU0AADAegQ0AADAegQ0AADAegQ0AADAegQ0AADAegQ0AAAgeAHN5s2bZdKkSZKXlyc5OTmycePGJr+/++67ZejQodKlSxfp3r27jB07Vt56662k9//AAw+Y/c6bNy/VQwMAAAGVckBTX18vhYWFsnLlypi/P+ecc+TRRx+Vd955R7Zs2SIDBw6UcePGyRdffNHivnfs2CG/+tWv5IILLkj1sAAAQIClPLHehAkTzC2eq6++usn9ZcuWyRNPPCFvv/22FBcXx33esWPHZNq0abJmzRq57777Uj0sAAAQYBmtoTlx4oQ8/vjjZkpjzeokctNNN8nEiRNNF1UyGhoazHTJ0TcAABBMGVn64IUXXpCrrrpKjh8/Ln379pWXX35ZevXqFXf7Z555RqqqqkyXU7KWLFki99xzj0NHDAAAbJaRgGbMmDGye/duOXLkiOlCmjp1qikM7t279ynbHjx4UG6++WYT9HTq1Cnp/2PRokVSVlYWua+LWuXn55OpAQDAIuHrdqvXyg61gj69vLy8xe0GDx4cuv/++2P+Tp+v+2nbtm3kpvdzcnLMv7/99tukjuXgwYPmedy4cePGjRs3se6m1/HWyMpq242NjabmJRYtFNYRUdFmzJhhhn7feuut0rZt26T+Dx1Grtmerl27mmHfTkaO/fv3N/tuzbLmtqMd/oq2+A7t8B3a4a9oi+/QDqm1g+ZHvv76a3Mdb42UAxodjVRdXR25X1NTY7qXevToIT179pTFixfLFVdcYWpntMtJh3cfOnRIpkyZ0iSIKSkpkdmzZ5sA5Pzzz2/yf+gcNrqv5o8n0qZNG+nXr59kir4ZQf5ghtEOf0VbfId2+A7t8Fe0xXdoh+TbQQcPtVbKAU1lZaWpkQkL17GUlpbK6tWr5YMPPpB169aZYEaDkpEjR0pFRYUUFBREnrN//37zewAAACekHNCMHj06YeHOhg0bWtzHxx9/nPD3r7/+eqqHBQAAAoy1nFrQsWNHueuuu8zPIKMd/oq2+A7t8B3a4a9oi+/QDu60Q45WBmflfwIAAMgQMjQAAMB6BDQAAMB6BDQAAMB6BDQAAMB6gQhoNm/eLJMmTTKzEOoswhs3bjxlskCd5E8n5uvcubOcd955Zk6daIcPH5bp06dLnz59zMR/w4cPl+eee67JNv/7v/8r06ZNMxMI/c3f/I380z/9k9m3Le3wxz/+Ua699lrz+9NOO00uv/xy+fDDD5ts83//939mZXSdY+j000+Xn/zkJ+Z50T755BOzcrruQ9fvWrBggXz77bfiJa1tC32v58yZI0OGDDGfGV1HbO7cuWZNMZvawonPRJiOL5gwYULM/QSlHd588035+7//e3OO0PPAD3/4Q/nmm2+sOUc41RZ+OF/qAsg6j5pO/qqf2SuvvFL27t2bkfOhTlWibaSjgQYPHixr164VP7XDnj175Gc/+5mZNVjPl+eee66sWLHilP+rte0QiICmvr5eCgsLzazFsejkgC+99JL85je/kffff1/mzZtnApznn38+ss0//uM/mjdRH9OlGiZPnmwW3dy1a1dkG/3j/MMf/mAW2tQVx/XE8POf/1xsaAe9GOkH9aOPPpLf/e535nUNGDBAxo4da54Xdsstt8h//ud/yrPPPitvvPGGfPbZZ6Ytwk6ePGn+eE+cOCFbt241kyzqh/LOO+8UL2ltW+jr1tuDDz4o7777rnmN+hnSk7JNbeHEZyJs+fLlMZcdCUo7aDCjF/dx48bJ9u3bZceOHeY8orOY23KOcKot/HC+1PObXqS3bdtmjvHPf/6zeW+dPh/qbPu6TXhRZ73+/PM//7Ns2rQp6685U+2wc+dOEwzpNVbf81/84hdmgelHH33U2XYIBUysBTULCgpC9957b5PHhg8fHvrFL34Rud+lS5fQv//7vzfZpkePHqE1a9aYf7/33ntm3zt27Ij8/sUXXzSLbB46dCjk9XbYu3eveezdd9+NPHby5MnQGWecEXmNf/rTn0Lt27cPPfvss5Ft3n//ffO8N99809z/7//+71CbNm1Chw8fjmyzatWqULdu3UINDQ0hL0qnLWJZv359qEOHDqE///nPVrZFa9ph165dob/9278Nff7556fsJyjtcPHFF4duv/32uPu17RzRmrbw2/lS1dbWmmN+4403HD0f/su//Iu5BkX76U9/Gho/fnzIL+0Qy6xZs0JjxoyJ3HeiHQKRoWnJqFGjzDcJXXNK/4Zfe+012bdvn4lCo7f57W9/a9KkutjmM888Y9JsOnNy+NuZpk1HjBgReY5+a9FvZ2+99ZZ4XXjx0E6d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",
      "text/plain": [
       "<Figure size 640x480 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "plt.scatter(x, y, s = 10)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[1880 1881 1882 1883 1884 1885 1886 1887 1888 1889 1890 1891 1892 1893\n",
      " 1894 1895 1896 1897 1898 1899 1900 1901 1902 1903 1904 1905 1906 1907\n",
      " 1908 1909 1910 1911 1912 1913 1914 1915 1916 1917 1918 1919 1920 1921\n",
      " 1922 1923 1924 1925 1926 1927 1928 1929 1930 1931 1932 1933 1934 1935\n",
      " 1936 1937 1938 1939 1940 1941 1942 1943 1944 1945 1946 1947 1948 1949\n",
      " 1950 1951 1952 1953 1954 1955 1956 1957 1958 1959 1960 1961 1962 1963\n",
      " 1964 1965 1966 1967 1968 1969 1970 1971 1972 1973 1974 1975 1976 1977\n",
      " 1978 1979 1980 1981 1982 1983 1984 1985 1986 1987 1988 1989 1990 1991\n",
      " 1992 1993 1994 1995 1996 1997 1998 1999 2000 2001 2002 2003 2004 2005\n",
      " 2006 2007 2008 2009 2010 2011 2012 2013 2014 2015 2016]\n"
     ]
    }
   ],
   "source": [
    "# 用二阶多项式去拟合\n",
    "\n",
    "order = 2 #多项式的阶数\n",
    "X = np.array([x**i for i in range(order+1)]).T\n",
    "print(x)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[      1    1880 3534400]\n",
      "(137, 3)\n"
     ]
    }
   ],
   "source": [
    "print(X[0])\n",
    "print(X.shape)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Task: implement yourself linear regression using numpy"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[np.float64(0.6633377993924867), np.float64(0.006820050590848294)]\n"
     ]
    }
   ],
   "source": [
    "n=len(x)\n",
    "x=x.ravel()\n",
    "sum_xy=np.sum(x*y)\n",
    "sum_x=np.sum(x)\n",
    "sum_y=np.sum(y)\n",
    "sum_x_square=np.sum(x**2)\n",
    "k=(sum_xy-sum_x*sum_y/n)/(sum_x_square-sum_x*sum_x/n) \n",
    "b=(sum_y/n-k*sum_x/n)\n",
    "\n",
    "W=[b,k]\n",
    "print(W)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Task: implement linear regression using the functions from sklearn\n",
    "\n",
    "[reference](https://scikit-learn.org/stable/modules/generated/sklearn.linear_model.LinearRegression.html#sklearn.linear_model.LinearRegression)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[[1247.08188291]\n",
      " [1247.74522071]\n",
      " [1248.40855851]\n",
      " [1249.0718963 ]\n",
      " [1249.7352341 ]\n",
      " [1250.3985719 ]\n",
      " [1251.0619097 ]\n",
      " [1251.7252475 ]\n",
      " [1252.3885853 ]\n",
      " [1253.0519231 ]\n",
      " [1253.7152609 ]\n",
      " [1254.3785987 ]\n",
      " [1255.0419365 ]\n",
      " [1255.7052743 ]\n",
      " [1256.3686121 ]\n",
      " [1257.0319499 ]\n",
      " [1257.6952877 ]\n",
      " [1258.3586255 ]\n",
      " [1259.0219633 ]\n",
      " [1259.68530109]\n",
      " [1260.34863889]\n",
      " [1261.01197669]\n",
      " [1261.67531449]\n",
      " [1262.33865229]\n",
      " [1263.00199009]\n",
      " [1263.66532789]\n",
      " [1264.32866569]\n",
      " [1264.99200349]\n",
      " [1265.65534129]\n",
      " [1266.31867909]\n",
      " [1266.98201689]\n",
      " [1267.64535469]\n",
      " [1268.30869249]\n",
      " [1268.97203029]\n",
      " [1269.63536809]\n",
      " [1270.29870589]\n",
      " [1270.96204368]\n",
      " [1271.62538148]\n",
      " [1272.28871928]\n",
      " [1272.95205708]\n",
      " [1273.61539488]\n",
      " [1274.27873268]\n",
      " [1274.94207048]\n",
      " [1275.60540828]\n",
      " [1276.26874608]\n",
      " [1276.93208388]\n",
      " [1277.59542168]\n",
      " [1278.25875948]\n",
      " [1278.92209728]\n",
      " [1279.58543508]\n",
      " [1280.24877288]\n",
      " [1280.91211068]\n",
      " [1281.57544847]\n",
      " [1282.23878627]\n",
      " [1282.90212407]\n",
      " [1283.56546187]\n",
      " [1284.22879967]\n",
      " [1284.89213747]\n",
      " [1285.55547527]\n",
      " [1286.21881307]\n",
      " [1286.88215087]\n",
      " [1287.54548867]\n",
      " [1288.20882647]\n",
      " [1288.87216427]\n",
      " [1289.53550207]\n",
      " [1290.19883987]\n",
      " [1290.86217767]\n",
      " [1291.52551547]\n",
      " [1292.18885327]\n",
      " [1292.85219106]\n",
      " [1293.51552886]\n",
      " [1294.17886666]\n",
      " [1294.84220446]\n",
      " [1295.50554226]\n",
      " [1296.16888006]\n",
      " [1296.83221786]\n",
      " [1297.49555566]\n",
      " [1298.15889346]\n",
      " [1298.82223126]\n",
      " [1299.48556906]\n",
      " [1300.14890686]\n",
      " [1300.81224466]\n",
      " [1301.47558246]\n",
      " [1302.13892026]\n",
      " [1302.80225806]\n",
      " [1303.46559585]\n",
      " [1304.12893365]\n",
      " [1304.79227145]\n",
      " [1305.45560925]\n",
      " [1306.11894705]\n",
      " [1306.78228485]\n",
      " [1307.44562265]\n",
      " [1308.10896045]\n",
      " [1308.77229825]\n",
      " [1309.43563605]\n",
      " [1310.09897385]\n",
      " [1310.76231165]\n",
      " [1311.42564945]\n",
      " [1312.08898725]\n",
      " [1312.75232505]\n",
      " [1313.41566285]\n",
      " [1314.07900064]\n",
      " [1314.74233844]\n",
      " [1315.40567624]\n",
      " [1316.06901404]\n",
      " [1316.73235184]\n",
      " [1317.39568964]\n",
      " [1318.05902744]\n",
      " [1318.72236524]\n",
      " [1319.38570304]\n",
      " [1320.04904084]\n",
      " [1320.71237864]\n",
      " [1321.37571644]\n",
      " [1322.03905424]\n",
      " [1322.70239204]\n",
      " [1323.36572984]\n",
      " [1324.02906764]\n",
      " [1324.69240544]\n",
      " [1325.35574323]\n",
      " [1326.01908103]\n",
      " [1326.68241883]\n",
      " [1327.34575663]\n",
      " [1328.00909443]\n",
      " [1328.67243223]\n",
      " [1329.33577003]\n",
      " [1329.99910783]\n",
      " [1330.66244563]\n",
      " [1331.32578343]\n",
      " [1331.98912123]\n",
      " [1332.65245903]\n",
      " [1333.31579683]\n",
      " [1333.97913463]\n",
      " [1334.64247243]\n",
      " [1335.30581023]\n",
      " [1335.96914802]\n",
      " [1336.63248582]\n",
      " [1337.29582362]]\n"
     ]
    }
   ],
   "source": [
    "model = LinearRegression()\n",
    "x=df['Year'].to_numpy().reshape(-1,1)\n",
    "model.fit(x, y)\n",
    "theta0 = model.intercept_\n",
    "theta1 = model.coef_[0]\n",
    "W_2 = [theta0,theta1]\n",
    "y_hat2=W_2[0]*x+W_2[1]\n",
    "print(y_hat2)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "verify your answer with codes below"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "our weight =  [np.float64(0.6633377993924867), np.float64(0.006820050590848294)]\n",
      "sklearn weight =  [np.float64(0.6633377993914209), np.float64(0.0068200505908488415)]\n"
     ]
    }
   ],
   "source": [
    "print(\"our weight = \", W)\n",
    "print(\"sklearn weight = \", W_2)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[<matplotlib.lines.Line2D at 0x26bacc03ed0>]"
      ]
     },
     "execution_count": 12,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "image/png": "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kAMAAKxEyAEAAFYi5AAAACsRcgAAgJUIOQAAwEqEHAAAYCVCDgAAsBIhBwAAWImQAwAArETIAQAAViLkAAAAKxFyAACAlQg5AADASoQcAABgJUIOAACwEiEHAABYiZADAACsRMgBAABWIuQAAAArEXIAAICVCDkAAMBKhBwAAGAlQg4AALASIQcAAFiJkAMAAKxEyAEAAFYi5AAAACsRcgAAgJUIOQAAwEqEHAAAYCVCDgAAsBIhBwAAWImQAwAArETIAQAAVgpIyPnss8/kF7/4hXTu3Fk6dOggffv2lW3btnnWO44jc+fOla5du5r12dnZsm/fPp9tHD16VMaOHSuJiYmSnJws48aNk8rKykDsLgAAsJDfQ86xY8fk+uuvl6ioKHnjjTfk448/lieffFI6derkKTN//nxZtGiRLF26VAoLCyU+Pl5ycnKkurraU0YDzq5du2Tt2rWyevVq2bRpk0yYMMHfuwsAACwV5mizih/NnDlT3n33XXn77bdbXK/frlu3bjJt2jS5//77zWvl5eWSlpYmy5YtkzFjxsju3bslIyNDtm7dKgMGDDBl1qxZI8OHD5fDhw+b93+biooKSUpKMtvW1iAAAND++fP67feWnNdff90Ek3/6p3+S1NRUueqqq+T555/3rN+/f78UFxebLiqXHkxmZqYUFBSY5/qoXVRuwFFaPjw83LT8tKSmpsZUjPcCAABCl99DzqeffipLliyRSy65RN58802555575N5775Xly5eb9RpwlLbceNPn7jp91IDkLTIyUlJSUjxlmsvPzzdhyV26d+/u70MDAAChHHIaGxvl6quvln//9383rTg6jmb8+PFm/E0g5eXlmaYtdzl06FBAvx8AAAixkKMzpnQ8jbc+ffrIwYMHzdfp6enmsaSkxKeMPnfX6WNpaanP+vr6ejPjyi3TXExMjOm7814AAEDo8nvI0ZlVe/bs8Xlt79690rNnT/N1r169TFBZt26dZ72On9GxNllZWea5PpaVlUlRUZGnzPr1600rkY7dAQAA+DaR4mf33XefXHfddaa76pZbbpEtW7bIc889ZxYVFhYmU6ZMkUceecSM29HQM2fOHDNjauTIkZ6Wn6FDh3q6uerq6mTSpElm5tXZzKwCAADw+xRypfe10TEyeoM/DTFTp041gcWl3/LBBx80wUdbbG644QZ59tln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tPzpzAP9GdKLgCsU6kEDjv5+NP8rTmdXDBw40MyWsKEezqYuunbtah417HrTmSQ6w0bZcJ74tnqw7XypA8fdgdHa2u/y17lQH5vPyNLn2vWtM5FsqAfXxx9/bFo2tQVn9uzZ4s1f9RA6f46fJW1S1aX5X+gRERGev8x0zIH6pjJZWVnmP1lbglx6AdD1egIINklJSebkpc3s+peY2xWhJzi9kK9bt85TVmdR6Elc60Dpo/7F5n0S01H5+sPa/AIQrPXgtuDoXyLaVKstGt7jFEKlHmbOnCkffvihuei5i9IWjBdffNG6evimurj44ovNtOrm02u11UNnINl2njhTPdhyvtTxmXph1z9edN969erls95f50It470Nt4y7DRvqQekYJJ05lZubK7/97W+lOb/VgxOCjh8/bmZ/6KJVsGDBAvP1gQMHzPof/vCHZlT3hg0bnE8//dR58cUXndjYWOfZZ58162tra53vfe97zsCBA53CwkLnb3/7m/PEE0+YmQD/8z//4/k+Q4cOda666ipT5p133nEuueQS57bbbnOCqS50hpDWw9///ndn5cqVTs+ePZ1Ro0b5bONXv/qV06NHD2f9+vXOtm3bnKysLLO46uvrncsvv9wZMmSIs2PHDmfNmjVm9kVeXp5jSz2Ul5ebmTR9+/Y1Pw86q8hd9PhDpR7OZkZOMNSDv+riqaeeMjNndKbJvn37zEwrPZfoz0iwnCfOtR5sOV/ec889TlJSkvPWW2/5/H6fOHHCr+dCvebExcU506dPN7OSFi9e7ERERJiyttTDzp07zXH/4he/8NmGztTydz2EZMjRX0j9ZW2+5ObmmvVa2XfddZfTrVs3c0Lq3bu38+STTzqNjY2ebezdu9f8Iqemppr/iCuuuOK0KZJfffWV+SVNSEgwJ7q7777bnDCCqS4WLlzoXHTRRWZKoP7Q6km6+TTfkydPmul/nTp1MnVx8803mzr09n//93/OsGHDnA4dOjhdunRxpk2b5plabUM9nOn9uuzfvz9k6uFsb9PQ3uvBn3WRn59vyunvhp7o33777aA6T/ijHmw4X57p91v/CPb3uVDr/MorrzS3oPiHf/gHn+9hQz08+OCDLW5DA7K/6yHs650GAACwCmNyAACAlQg5AADASoQcAABgJUIOAACwEiEHAABYiZADAACsRMgBAABWIuQAAAArEXIAAICVCDkAAMBKhBwAACA2+n94wfG6qziXzwAAAABJRU5ErkJggg==",
      "text/plain": [
       "<Figure size 640x480 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "plt.scatter(x, y, s=10, c=\"r\")\n",
    "y_hat=W[0]*x+W[1]\n",
    "y_hat2=W_2[0]*x+W_2[1]\n",
    "plt.plot(x, y_hat,c=\"k\")\n",
    "plt.plot(x, y_hat2,c=\"b\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Linear Regression"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 31,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "(350, 200) (350,)\n",
      "(150, 200) (150,)\n"
     ]
    }
   ],
   "source": [
    "N_SAMPLES = 500\n",
    "N_FEATURES = 200\n",
    "NOISE = 3\n",
    "data = datasets.make_regression(n_samples=N_SAMPLES, \n",
    "                                n_features=N_FEATURES, \n",
    "                                n_informative=5, \n",
    "                                noise=NOISE, \n",
    "                                random_state=9961)\n",
    "X = data[0]\n",
    "y = data[1]\n",
    "X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=9961)\n",
    "print(X_train.shape, y_train.shape)\n",
    "print(X_test.shape, y_test.shape)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Task: use numpy to implement linear regression via the normal equation, compute the L2 and L1 norms of the learned weights, and evaluate the mean squared error on both training and test data."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "200\n",
      "L2 范数 ||w||₂ = 128.1208\n",
      "L1 范数 ||w||₁ = 286.8087\n",
      "训练集 MSE = 4.1203\n",
      "测试集 MSE = 19.9275\n"
     ]
    }
   ],
   "source": [
    "Xb_train = np.hstack([np.ones((X_train.shape[0], 1)), X_train])  \n",
    "Xb_test  = np.hstack([np.ones((X_test.shape[0], 1)),  X_test ])  \n",
    "theta = np.linalg.pinv(Xb_train.T.dot(Xb_train)).dot(Xb_train.T).dot(y_train)\n",
    "w = theta[1:]       # 长度为 N_FEATURES 的权重向量\n",
    "l2_norm = np.linalg.norm(w, ord=2)\n",
    "l1_norm = np.linalg.norm(w, ord=1)\n",
    "print(len(w))\n",
    "print(f\"L2 范数 ||w||₂ = {l2_norm:.4f}\")\n",
    "print(f\"L1 范数 ||w||₁ = {l1_norm:.4f}\")\n",
    "y_train_pred = Xb_train.dot(theta)\n",
    "y_test_pred  = Xb_test.dot(theta)\n",
    "\n",
    "mse_train = np.mean((y_train_pred - y_train)**2)\n",
    "mse_test  = np.mean((y_test_pred  - y_test )**2)\n",
    "\n",
    "print(f\"训练集 MSE = {mse_train:.4f}\")\n",
    "print(f\"测试集 MSE = {mse_test :.4f}\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Task: use scikit-learn’s LinearRegression to fit the same model without an intercept, compute the L2 and L1 norms of the learned weights, and evaluate the mean squared error on both training and test data."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 29,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "L2 范数 ||w||₂ = 128.1182\n",
      "L1 范数 ||w||₁ = 286.7610\n",
      "训练集 MSE = 4.1203\n",
      "测试集 MSE = 19.9275\n"
     ]
    }
   ],
   "source": [
    "from sklearn.metrics import mean_squared_error\n",
    "model = LinearRegression(fit_intercept=False)\n",
    "model.fit(X_train, y_train)\n",
    "w_2 = model.coef_\n",
    "l2_norm1 = np.linalg.norm(w_2, ord=2)\n",
    "l1_norm1 = np.linalg.norm(w_2, ord=1)\n",
    "y_train_pred1 = model.predict(X_train)\n",
    "y_test_pred1 = model.predict(X_test)\n",
    "mse_train1 = mean_squared_error(y_train, y_train_pred)\n",
    "mse_test1 = mean_squared_error(y_test, y_test_pred)\n",
    "\n",
    "# 打印结果\n",
    "print(f\"L2 范数 ||w||₂ = {l2_norm1:.4f}\")\n",
    "print(f\"L1 范数 ||w||₁ = {l1_norm1:.4f}\")\n",
    "print(f\"训练集 MSE = {mse_train1:.4f}\")\n",
    "print(f\"测试集 MSE = {mse_test1 :.4f}\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Ridge Regression"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Task: use numpy to implement ridge regression with various values of regularization strength via the closed-form solution, compute the L2 norm of the learned weights, and evaluate the mean squared error on both training and test data."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 60,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "128.1182   4.1222   19.8465\n",
      "128.1099   4.1223   19.8253\n",
      "128.0356   4.1253   19.6491\n",
      "127.3059   4.4166   19.2392\n",
      "121.0602   27.7303   108.5363\n",
      "91.2044   845.0259   2144.1586\n"
     ]
    }
   ],
   "source": [
    "alphas = [0, 0.01, 0.1, 1, 10, 100]\n",
    "results = []\n",
    "def ridge_regression(X, y, alpha):\n",
    "    n_features = X.shape[1]\n",
    "    return np.linalg.inv(X.T @ X + alpha * np.eye(n_features)) @ X.T @ y \n",
    "for alpha in alphas:\n",
    "    weights = ridge_regression(X_train, y_train, alpha)\n",
    "    l2_norm = np.linalg.norm(weights, ord=2)\n",
    "    y_train_pred = X_train @ weights\n",
    "    y_test_pred = X_test @ weights\n",
    "    train_mse = mean_squared_error(y_train, y_train_pred)\n",
    "    test_mse = mean_squared_error(y_test, y_test_pred)\n",
    "    results.append({\n",
    "    'alpha': alpha,\n",
    "    'weights': weights,\n",
    "    'l2_norm': l2_norm,\n",
    "    'train_mse': train_mse,\n",
    "    'test_mse': test_mse})\n",
    "for res in results:\n",
    "    print(f\"{res['l2_norm']:<.4f}   {res['train_mse']:<.4f}   {res['test_mse']:<.4f}\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Task: use scikit-learn’s Ridge to fit a ridge-regression model with various values of $\\lambda$ and no intercept, compute the L2 norm of the learned weights, and evaluate the mean squared error on both training and test data."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 57,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "128.1182   4.1222   19.8465\n",
      "128.1099   4.1223   19.8253\n",
      "128.0356   4.1253   19.6491\n",
      "127.3059   4.4166   19.2392\n",
      "121.0602   27.7303   108.5363\n",
      "91.2044   845.0259   2144.1586\n"
     ]
    }
   ],
   "source": [
    "alphas = [0, 0.01, 0.1, 1, 10, 100]\n",
    "results = []\n",
    "for alpha in alphas:\n",
    "    model = Ridge(alpha=alpha, fit_intercept=False)\n",
    "    model.fit(X_train, y_train)\n",
    "    weights = model.coef_\n",
    "    l2_norm = np.linalg.norm(weights, ord=2)\n",
    "    y_train_pred = model.predict(X_train)\n",
    "    y_test_pred = model.predict(X_test)\n",
    "    train_mse = mean_squared_error(y_train, y_train_pred)\n",
    "    test_mse = mean_squared_error(y_test, y_test_pred)\n",
    "    results.append({\n",
    "        'alpha': alpha,\n",
    "        'weights': weights,\n",
    "        'l2_norm': l2_norm,\n",
    "        'train_mse': train_mse,\n",
    "        'test_mse': test_mse})\n",
    "for res in results:\n",
    "    print(f\"{res['l2_norm']:<.4f}   {res['train_mse']:<.4f}   {res['test_mse']:<.4f}\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Lasso"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Task: use scikit-learn’s Lasso to fit a Lasso-regression model with various values of $\\lambda$ and no intercept, compute the L1 norm of the learned weights, report the mean squared error on both training and test data, and count the number of non-zero weights."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 62,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "286.8087   4.2101   15.4694\n",
      "286.8087   6.2590   9.6713\n",
      "286.8087   13.3627   12.2386\n",
      "286.8087   413.5681   344.6278\n",
      "286.8087   16480.1415   15233.7168\n"
     ]
    }
   ],
   "source": [
    "alphas = [0.01, 0.1, 1, 10, 100]\n",
    "results = []\n",
    "for alpha in alphas:\n",
    "    model = Lasso(alpha=alpha, fit_intercept=False)\n",
    "    model.fit(X_train, y_train)\n",
    "    weights = model.coef_\n",
    "    l2_norm = np.linalg.norm(weights, ord=1)\n",
    "    y_train_pred = model.predict(X_train)\n",
    "    y_test_pred = model.predict(X_test)\n",
    "    train_mse = mean_squared_error(y_train, y_train_pred)\n",
    "    test_mse = mean_squared_error(y_test, y_test_pred)\n",
    "    results.append({\n",
    "        'alpha': alpha,\n",
    "        'weights': weights,\n",
    "        'l1_norm': l1_norm,\n",
    "        'train_mse': train_mse,\n",
    "        'test_mse': test_mse})\n",
    "for res in results:\n",
    "    print(f\"{res['l1_norm']:<.4f}   {res['train_mse']:<.4f}   {res['test_mse']:<.4f}\")"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "base",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.13.5"
  },
  "orig_nbformat": 4
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
